package cn.zf233.xcloud.web;

import cn.zf233.xcloud.commom.Const;
import cn.zf233.xcloud.commom.R;
import cn.zf233.xcloud.commom.enums.UserRoleENUM;
import cn.zf233.xcloud.entity.System;
import cn.zf233.xcloud.entity.User;
import cn.zf233.xcloud.service.AdminService;
import cn.zf233.xcloud.service.SystemService;
import cn.zf233.xcloud.service.UserService;
import cn.zf233.xcloud.service.core.MemoryCoordinate;
import cn.zf233.xcloud.util.EmailUtil;
import cn.zf233.xcloud.vo.UserVo;
import com.sun.management.OperatingSystemMXBean;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.lang.management.ManagementFactory;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by zf233 on 2021/1/17
 * 管理员请求控制器
 */
@Controller
public class AdminController {

    private final DecimalFormat format = new DecimalFormat("#.00");
    public static final String MEMORY_MACHINE = "machine";
    public static final String MEMORY_JVM = "jvm";
    public static final String MEMORY_LIMIT = "limit";
    public static final String LOAD_SYSTEM_CPU = "systemCpuLoad";

    @Resource
    private AdminService adminService;

    @Resource
    private UserService userService;

    @Resource
    private SystemService systemService;

    @Resource
    private EmailUtil emailUtil;

    @Resource
    private MemoryCoordinate memory;

    // 后台主页
    @RequestMapping("/admin")
    public String home(HttpSession session) {
        UserVo currentAdmin = (UserVo) session.getAttribute(Const.CURRENT_USER);
        if (currentAdmin != null && UserRoleENUM.ADMIN.getCode().equals(currentAdmin.getRoleNum())) {
            return "admin";
        }
        return "redirect:/user/jump/index";
    }

    @RequestMapping("/admin/list")
    @ResponseBody
    public R list(HttpSession session,
                  @RequestParam(required = false) Integer role) {
        Object currentAdmin = session.getAttribute(Const.CURRENT_USER);
        if (currentAdmin == null) {
            return R.createByErrorIllegalArgument("登陆失效，请重新登陆");
        }
        return adminService.getAllUserInfo(role);
    }

    // 移除用户
    @RequestMapping("/admin/remove")
    @ResponseBody
    public R remove(HttpSession session, User user) {
        Object currentAdmin = session.getAttribute(Const.CURRENT_USER);
        if (currentAdmin == null) {
            return R.createByErrorIllegalArgument("登陆失效，请重新登陆");
        }
        return adminService.removeUser(user);
    }

    // 设置用户状态（锁定/解锁）
    @RequestMapping("/admin/lock")
    @ResponseBody
    public R setLock(HttpSession session, User user, Integer lock) {
        Object currentAdmin = session.getAttribute(Const.CURRENT_USER);
        if (currentAdmin == null) {
            return R.createByErrorIllegalArgument("登陆失效，请重新登陆");
        }
        return adminService.lockOrUnlock(user, lock);
    }

    // 获取用户详情
    @RequestMapping("/admin/detail")
    @ResponseBody
    public R setRole(HttpSession session, User user) {
        Object currentAdmin = session.getAttribute(Const.CURRENT_USER);
        if (currentAdmin == null) {
            return R.createByErrorIllegalArgument("登陆失效，请重新登陆");
        }
        R<UserVo> r = userService.getUserVoByPrimaryKey(user.getId());
        if (r.isSuccess()) {
            adminService.setIpInfo(r.getData());
        }
        return r;
    }

    // 获取用户详情
    @RequestMapping("/admin/chart/user")
    @ResponseBody
    public R chart(HttpSession session) {
        Object currentAdmin = session.getAttribute(Const.CURRENT_USER);
        if (currentAdmin == null) {
            return R.createByErrorIllegalArgument("登陆失效，请重新登陆");
        }
        return adminService.userTypeChart();
    }

    @RequestMapping("/admin/chart/flow")
    @ResponseBody
    public R<Map<String, Object>> flowChart() {
        return adminService.flowChart();
    }

    @RequestMapping("/admin/chart/memory")
    @ResponseBody
    public R<Map<String, Object>> get() { // 获取内存占用百分比
        Map<String, Object> map = new HashMap<>(4);
        Runtime runtime = Runtime.getRuntime();
        OperatingSystemMXBean bean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
        long machineFree = bean.getFreePhysicalMemorySize();
        long machineTotal = bean.getTotalPhysicalMemorySize();
        double systemCpuLoad = bean.getSystemCpuLoad();
        long use = memory.use();
        String machine = this.format.format((machineTotal - machineFree) / (double) machineTotal * 100.0);
        String jvm = this.format.format((runtime.totalMemory() - runtime.freeMemory()) / (double) runtime.totalMemory() * 100.0);
        String limit = this.format.format((use / (double) MemoryCoordinate.MAX) * 100.0);
        String cpuLoad = this.format.format(systemCpuLoad * 100.0);
        map.put(MEMORY_MACHINE, machine);
        map.put(MEMORY_JVM, jvm);
        map.put(MEMORY_LIMIT, limit);
        map.put(LOAD_SYSTEM_CPU, cpuLoad);
        return R.createBySuccess("JVM内存占用图表参数获取成功", map);
    }

    @PostMapping(value = "/admin/feedback")
    @ResponseBody
    public R message(String contact, String content) {
        if (StringUtils.isNotBlank(contact) && StringUtils.isNotBlank(content)) {
            emailUtil.sendSimpleEmail("13784570379@163.com",
                    "用户意见反馈",
                    "收到一条意见反馈\n联系方式:" + contact + "\n反馈内容:" + content);
            return R.createBySuccessMessage("感谢您的反馈！");
        }
        return R.createByErrorIllegalArgument("意见反馈失败");
    }

    @GetMapping("/admin/system/argument/get")
    @ResponseBody
    public R<System> getSystem() {
        return systemService.getSystem();
    }

    @PostMapping("/admin/system/argument")
    @ResponseBody
    public R updateSystem(System system) {
        return systemService.update(system);
    }

    @GetMapping("/admin/calibration")
    @ResponseBody
    public R calibration() {
        return userService.refreshUserLevelTask();
    }

    @GetMapping("/admin/agreement")
    public String agreement() {
        R<String> url = systemService.getBookUrl();
        return "redirect:" + url.getData();
    }

    @GetMapping("/admin/app")
    public String app() {
        R<String> url = systemService.getAppUrl();
        return "redirect:" + url.getData();
    }

    @GetMapping("/admin/starter")
    public String starter() {
        R<String> url = systemService.getStarterUrl();
        return "redirect:" + url.getData();
    }

    @GetMapping("/admin/toast/index")
    @ResponseBody
    public R indexToast() {
        return systemService.getIndexToast();
    }

    @GetMapping("/admin/toast/home")
    @ResponseBody
    public R homeToast() {
        return systemService.getHomeToast();
    }
}
